//类型断言： 
/**
 * 语法：
    变量 as 类型;
    <string> 变量;
 */
let c:string;
let d:unknown;
d="xdclass";
c=d as 'string';
// TS中的函数
// 1、对函数中形参进行类型声明


// 如何设置函数声明中的形参的类型声明呢？
// 语法：
//     function fun(形参1:number,形参2:number){
//         console.log(形参1+形参2);
//     }
function fun1(name:string,numbers:number){
return console.log(name + numbers);

}
    //调用
    //传递不是number的实参
    // fun('xdclass','net');//TS解析器提示报错，不允许这样做，我们必须按照函数声明的形参类型传递参数
    //正确的参数
    fun1('shj',456);
    //多参数
    // fun(123,4556,55,56);//TS解析器报错
    //少参数
    // fun(11);//TS解析器报错
// 2、函数中返回值类型的声明


// 第一种情况：不设置返回值类型，但是有返回值
function fun(){
    return true;
}
// 这个时候TS解析器会根据返回值的类型进行判断，返回值类型是什么函数返回值类型就是什么
let result=fun();
console.log(typeof result);

// 第二种情况：设置返回值类型为void
// void:用来表示空，以函数为例，就表示没有返回值的函数
function fun2():void{
    // return 'a';//提示报错
    // return 123;//提示报错
    // return true;//提示报错
    return undefined;//不提示报错
    // return null;//不提示报错
    return;//不提示报错
}

// 第三种情况：设置返回值类型为 never
// never:永远不会返回结果

function fun3():never{
    throw new Error("出错了！！");
    //程序报错代码立即结束，立即结束以后就不会有返回值了,这个东西用的相对比较少，了解一下知道一下就行了
}
//-----------
// TS中的对象类型声明
let a1:object;   //这就表示声明一个变量，类型为object,也就是说a只能用来报存一个对象
//object表示一个对象

// 用来指定对象中可以包含哪些属性
// 语法：
//     {属性名:属性值，属性名1:属性值1}
// 注意当我们通过这种方式指定对象的时候，你写的这个对象必须要这个要求指定对象的格式必须一模一样
// ​
// ​
//     情景一：我们指定的对象它必须包含一个name,但是还有age和sex这个俩个变量是可能有可能有没有的，这种情况我们该怎样做呢？
// ​
// 这种情况下我我们在属性名后面加个?，它就表示这个属性可选，既可以有也可以无；
// ​
// 例如
let b:{name:string,age?:number,sex?:string};
​
b={name:'帆哥'};
b={name:'小帆',age:12};
// 情景二：当我们只知道我们必须有的属性，而其他的不必须我们不知道，我们该怎么处理呢？
// 我们可以通过下面这个方式实现
let bs:{names:string,[propName:string]:unknown};
bs={
    names:'aa',
    sya(){}
}
//这就表示我们指定b中存储的类型是对象，并且这个对象必须含有一个name的属性，类型为string,这个对象还可以有其他可选属性，只要属性名满足是字符串，属性值是unknown即可
// [propName:string]:
//     propName:这个任意命名，就表示属性的名字，这个属性名字的类型是string。js中属性名一般都是用string定义
//     [propName:string]:unknown;合起来就代表属性名为string类型，为可选的并且这个属性的值为unknown类型



//-----------

//TS中数组类型声明
// 在TS我们可以通过
let e1:string[];//声明一个数组
// string[];//表示字符串数组
// e1=['a','b','xdclass',1];//但是你存一个TS解析器就是提示报错
// 再创建一个number型的数组
let d1:number[];
// boolean型的数组
let e2:boolean[];
// 另外一种数组的声明方式
let e:Array<number>;

// 数组类型声明的语法：
    // 第一种：
    //     let 变量名:类型名[];
    // 第二种：
    //     let 变量名:Array<类型名>;
        
        
// 假如你还想创建一个能存储任意类型的数组。怎么办呢？
// 可以这样做
let e3:Array<any>;
let e4:any[];

//-----
// TS中的扩展类型tuple  tabo

// 简介：详解TS中的扩展类型tuple

// 1、tuple：叫做元组

// 2、什么是元组呢？

// 	元组就是定长的数组。（就代表数组中的数量是固定的就叫做元组，元组的存储效率比较好点，因为元组是固定，不会出现扩容的现象，所有效率会好点）

// 	使用场景：

// 		就是数组的数量是固定的，这时候用元组是比较好的选择。

// 3、元组怎么写呢？


let h:[string,string];//这就表示我定义一个元组，在这个元组中有两个，第一个值是string类型。第二个值也是string
//定义的时候多一个少一个也不行，必须按照声明的结构定义数组，不然TS解析器就会提示报错
h=['xdclass','net',];
// 元组书写语法：[类型，类型,类型]；//这个不会特别长，元素多的话还是用数组
// ok这就是TS中的元组



//TS中Enum  枚举
// 1、什么是enum（枚举）?


// 在数学和计算机科学理论中，一个集的枚举是列出某些有穷序列集的所有成员的程序，或者是一种特定类型对象的计数
// 2、TS中的枚举Enum


// 使用枚举，可以定义一些带名字的常量。用于清晰地表达意图或创建一组有区别的用例。
// ​
// 语法：
//     enum 枚举名称{成员1，成员2....};
// 1）：数字枚举
//     默认情况下，第一个枚举值是0，后续至依次增1
    // enum Color 
    // { 
    // red,
    // blue,
    // yellow
    // }
    
    // let col = Color.blue;
    // alert(col);
    // 1
// 2）：字符串枚举
    // enum Gender {
    //     male = '1',
    //     female = '0',
    // }

    // alert(Gender.male);
    // "1"


    //TS中联合类型声明
//     在ts中我们可以使用   "|" 进行联合类型声明
// ​
// 语法：
//     let 变量名:声明类型1|声明类型2.....;
    //可以是任意多个
let aa:number |string
aa=11
    //就表示声明一个变量名，它可以是类型1还可以是类型2

    //---------
    //TS中类型别名
    // 语法：
    //   type 类型别名的名字=string;
       type myType='123' | '1';
    // 现在可以看做myType和string是等价的
    // 我们测试一下
    let b1:string;
    let c1:myType;

    // type myType1=1|2|3|4|5|;

    // let k1:myType1;
    // let p1:myType1;
    